<?php
/**
 * Created by PhpStorm.
 * User: tc-net
 * Date: 2021/8/10
 * Time: 14:06
 */
class Esign{
    public $host            =   "";//请求网关host
    public $project_id      =   "";//应用id
    public $project_scert   =   "";//密钥
    public $debug           =   true;
    public $debug_path      =   "";
    public $name            =   "家政服务合同";
//    public $sealId          =   "";//印章id
    public $fileId          =   null;
    public $doc             =   [];
    public $signers         =   [];
    public $attachments     =   [];
    public $copiers         =   [];//抄送人人列表
    public $flowInfo        =   null;
    public function __construct($param) {
        $this->host         = isset($param['host']) ? $param['host'] : "https://smlopenapi.esign.cn";
        $this->project_id   = isset($param['project_id']) ? $param['project_id'] : "";
        $this->project_scert= isset($param['project_scert']) ? $param['project_scert'] : "";
        $this->debug        = isset($param['debug']) ? boolval($param['debug']) : true;
        $this->debug_path   = isset($param['debug_path']) ? $param['debug_path'] : __DIR__;
        $this->name         = isset($param['name']) ? $param['name'] : "家政服务合同";
//        $this->sealId       = isset($param['sealId']) ? $param['sealId'] : "";
        if($this->debug&&!is_writable($this->debug_path)){
            throw new \Exception("日志目录 {$this->debug_path} 不可写");
        }
        \Esign\Factory\Factory::init($this->host,$this->project_id,$this->project_scert);
        \Esign\Factory\Factory::setDebug($this->debug);//是否开启日志记录，传true或false,日志存放在根目录的phplog.txt文件
        \Esign\Factory\Factory::setDebugPath($this->debug_path);
    }

    /**
     * 发起合同
     * @return mixed
     * @throws Exception
     */
    public function send(){
        $createFlowOneStep = new \Esign\Factory\Signfile\CreateFlowOneStep();
        if(empty($this->doc)){
            throw new \Exception("需设置待签文档信息");
        }
        $createFlowOneStep->setDoc($this->doc);
        if(empty($this->flowInfo)){
            throw new \Exception("需设置流程基本信息");
        }
        $createFlowOneStep->setFlowInfo($this->flowInfo);
        if(!empty($this->signers)){
            $createFlowOneStep->setSigners($this->signers);
        }
        if(!empty($attachments)){
            $createFlowOneStep->setAttachments($this->attachments);
        }
        if(!empty($this->copiers)){
            $createFlowOneStep->setCopiers($this->copiers);
        }
        $flowOneStepResp = $createFlowOneStep->execute();
        $flowOneStepJson = json_decode($flowOneStepResp->getBody());
        return $flowOneStepJson->data->flowId;//流程id保存好

    }

    /**
     * 设置待签文档信息
     * @return $this
     */
    public function setDoc($templateId,$simpleFormFields){
        $doc = new \Esign\Factory\Bean\Doc();
        $file_template = \Esign\Factory\Base\FileTemplate::createFileByTemplate($this->name,$templateId,$simpleFormFields);
        $file_template_resp = $file_template->execute()->getBody();
        $this->fileId = $file_template_resp->data->fileId;//文件id保存好，后续使用
        $doc->setFileId($this->fileId);
        $doc->setFileName("{$this->name}.pdf");
        $this->doc[] = $doc;
        return $this;
    }
    /**
     * 设置流程基本信息
     * @param $param
     * @return $this
     */
    public function setFlowInfo($param){
        $flowInfo = new \Esign\Factory\Bean\FlowInfo();
        $flowInfo->setBusinessScene($this->name);//文件主题
        $flowInfo->setAutoArchive(true);//自动归档
        $flowInfo->setAutoInitiate(true);//自动开启流程
        $flowInfo->setSignValidity(isset($param['sign_deadline'])&&!empty($param['sign_deadline']) ? strtotime($param['sign_deadline']." 23:59:59")*1000 : strtotime("+1 month")*1000);
        $flowInfo->setContractValidity(isset($param['sign_deadline'])&&!empty($param['sign_deadline']) ? strtotime($param['sign_deadline']." 23:59:59")*1000 : strtotime("+1 month")*1000);   //文件有效截止日期，时间戳格式，毫秒，默认不失效
        $flowInfo->setInitiatorAccountId($param['initiatorAccountId']);//	发起方账户id
        $flowInfo->setInitiatorAuthorizedAccountId($param['initiatorAuthorizedAccountId']);   //	发起方主体id
        $flowInfo->setFlowConfigInfo([
            "noticeDeveloperUrl"    =>  $param['noticeDeveloperUrl'],
            "noticeType"            =>  1,
            "signPlatform"          =>  "1,2"
        ]);
        $this->flowInfo = $flowInfo;
        return $this;
    }

    /**
     * 设置自动签署方签署者
     * @param array $param
     * thirdOrderNo
     * sealId
     * pos[page]
     * pos[x]
     * pos[y]
     * @return $this
     * @throws Exception
     */
    public function setAutoSigner(array $param){
        if(empty($this->fileId)){
            throw new \Exception("需先设置待签文档信息");
        }
        $signer_company = new \Esign\Factory\Bean\Signer();
        $signer_company->setPlatformSign(true);
        $signer_company->setSignOrder(1);
        if(isset($param['thirdOrderNo'])){
            $signer_company->setThirdOrderNo($param['thirdOrderNo']);
        }
        $sign_field = new \Esign\Factory\Bean\Signfield();
        $sign_field->setAutoExecute(true);//自动签署
        $sign_field->setActorIndentityType(2);
        $sign_field->setFileId($this->fileId);
        if(isset($param['sealId'])){
            $sign_field->setSealId($param['sealId']);//印章id
            $sign_field->setSignType(1);
        }
        $posBean = new \Esign\Factory\Bean\PosBean();
        $sign_field->setPosBean($posBean->setPosPage($param['pos']['page'])->setPosX($param['pos']['x'])->setPosY($param['pos']['y']));
        $sign_field->setWidth(100);
        $sign_field->setSignDateBeanType(0);
        $signer_company->setSignfields([$sign_field]);
        $this->signers[] = $signer_company;
        return $this;
    }

    /**
     * 设置签署方签署者
     * @param array $param
     * @return $this
     * @throws Exception
     */
    public function setSigner(array $param){
        if(empty($this->fileId)){
            throw new \Exception("需先设置待签文档信息");
        }
        //查询个人
        try{
            $account = new \Esign\Factory\Account\QryPersonByThirdId($param['customer_cred_number']);
            $accountInfo = json_decode($account->execute()->getBody(),true);
//            $createPsn = Account::createPersonByThirdPartyUserId(
//                $thirdPartyUserIdPsn,
//                $namePsn,
//                $idTypePsn,
//                $idNumberPsn);
//            $createPsn->setMobile($mobilePsn);
//            $createPsnResp = $createPsn->execute();//execute方法发起请求
//            $createPsnJson = json_decode($createPsnResp->getBody());
        }catch (\Exception $e){
            $accountInfo = null;
        }
        if(!empty($accountInfo)&&isset($accountInfo['data']['thirdPartyUserId'])){
            $esign_account_info_diff = array_diff_assoc([
                "name"      =>  $param['name'],
                "mobile"    =>  $param['mobile'],
                "idType"    =>  $param['idType'],
                "idNumber"  =>  $param['idNumber'],
//                            "idType"   =>  $param['customer_cred_type'],
            ],$accountInfo['data']);
            if(!empty($esign_account_info_diff)){
                if(isset($esign_account_info_diff['idNumber'])&&!empty($accountInfo['data']['idNumber'])){
                    //证件号，该字段只有为空才允许修改
                    $accountInfo = null;
                    $account = new \Esign\Factory\Account\DeletePersonByThirdId($accountInfo['data']['thirdPartyUserId']);
                    $resp    = json_decode($account->execute()->getBody(),true);
                    if($resp['code']!=0){
                        throw new \Exception("注销{$accountInfo['data']['thirdPartyUserId']}信息失败");
                    }
                }else{
                    try{
                        $account = new \Esign\Factory\Account\UpdatePersonAccountByThirdId($accountInfo['data']['thirdPartyUserId']);
                        $account->setName($param['name']);
                        $account->setMobile($param['mobile']);
                        $accountInfo = json_decode($account->execute()->getBody(),true);
                    }catch (\Exception $e){
                        throw new \Exception("更新业主e签宝个人信息失败：{$e->getMessage()}");
                    }
                }
            }
        }
        if(empty($accountInfo)){
            //创建
            try{
                //$thirdPartyUserId, $name, $idType, $idNumber
                $account = new \Esign\Factory\Account\CreatePersonByThirdPartyUserId($param['thirdPartyUserId'],$param['name'],$param['idType'],$param['idNumber']);
                $account->setMobile($param['mobile']);
                $accountInfo = json_decode($account->execute()->getBody(),true);
            }catch (\Exception $e){
                throw new Exception("创建业主e签宝个人信息失败：{$e->getMessage()}");
            }
        }
        $accountId = $accountInfo['data']['accountId'];
        $signer = new \Esign\Factory\Bean\Signer();
        $signer->setPlatformSign(false);
        $signer->setSignOrder(1);
        $signerAccount = new \Esign\Factory\Bean\SignerAccount();
        $signerAccount->setSignerAccountId($accountId);
        $signer->setSignerAccount($signerAccount);
        if(isset($param['thirdOrderNo'])){
            $signer->setThirdOrderNo($param['thirdOrderNo']);
        }
        $sign_field = new \Esign\Factory\Bean\Signfield();
        $sign_field->setAutoExecute(false);//自动签署
        $sign_field->setFileId($this->fileId);
        $sign_field->setSignType(1);
        $posBean = new \Esign\Factory\Bean\PosBean();
        $sign_field->setPosBean($posBean->setPosPage($param['pos']['page'])->setPosX($param['pos']['x'])->setPosY($param['pos']['y']));
        $sign_field->setWidth(80);
        $sign_field->setSignDateBeanType(0);
        $signer->setSignfields([$sign_field]);
        $this->signers[] = $signer;
        return $this;
    }

    /**
     * 设置附件信息
     * @param $attachment
     * @return $this
     */
    public function setAttachments($attachment){
        if(isset($attachment['file_id'])&&$attachment['file_name']){
            $attachment = new \Esign\Factory\Bean\Attachment();
            $attachment->setFileId($attachment['file_id']);
            $attachment->getAttachmentName($attachment['file_name']);
            $this->attachments[] = $attachment;
        }
        return $this;
    }
    /**
     * 设置抄送人人列表
     * @param $copier
     * @return $this
     */
    public function setCopiers($copier){
        if(isset($copier['account_id'])&&$copier['account_type']){
            $copiers = new \Esign\Factory\Bean\Copier();
            $copiers->setCopierAccountId($copier['account_id']);
            $copiers->setCopierIdentityAccountType($copier['account_type']);
            $this->copiers[] = $copiers;
        }
        return $this;
    }

    /**
     * 获取签署url
     * @param $flowId
     * @param $accountId
     * @return mixed
     */
    public function getSignUrl($flowId,$accountId){
        $getFileSignUrl = \Esign\Factory\Base\SignFile::getFileSignUrl($flowId, $accountId);
//        $getFileSignUrl->setOrganizeId($orgId);
        $getFileSignUrlResp = $getFileSignUrl->execute();
        $getFileSignUrlJson = json_decode($getFileSignUrlResp->getBody());
        return $getFileSignUrlJson->data->shortUrl;
    }
}